//! Zenop2p 主程序：简化版本，专注于基本网络功能
use libp2p::{
    identity::Keypair,
    noise::Config as NoiseConfig,
    swarm::Swarm,
    tcp::{Config as TcpConfig, tokio::Transport as TokioTcpTransport},
    yamux::Config as YamuxConfig,
    Transport, PeerId,
};
use libp2p::futures::StreamExt;
use std::time::Duration;
use tracing_subscriber::EnvFilter;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化日志
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();

    println!("启动简单的 libp2p 网络示例...");

    // 1. 生成密钥对和节点ID
    let keypair = Keypair::generate_ed25519();
    let peer_id = PeerId::from(keypair.public());

    // 2. 配置传输层（TCP + 加密 + 流复用）
    let transport = TokioTcpTransport::new(TcpConfig::default().nodelay(true))
        .upgrade(libp2p::core::upgrade::Version::V1)
        .authenticate(NoiseConfig::new(&keypair)?)
        .multiplex(YamuxConfig::default())
        .boxed();

    // 3. 创建一个简单的 ping 行为
    let behaviour = libp2p::ping::Behaviour::new(libp2p::ping::Config::default());

    // 4. 创建 Swarm
    let mut swarm = Swarm::new(transport, behaviour, peer_id, libp2p::swarm::Config::with_tokio_executor());

    // 5. 监听本地端口
    swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;

    // 6. 打印节点信息
    println!("节点ID: {}", peer_id);
    println!("网络已启动，监听地址: {:?}", swarm.listeners().collect::<Vec<_>>());

    // 7. 简单的事件循环（运行5秒后退出）
    let start_time = std::time::Instant::now();
    let duration = Duration::from_secs(5);
    
    loop {
        if start_time.elapsed() >= duration {
            println!("测试完成，程序退出");
            break;
        }
        
        match swarm.select_next_some().await {
            libp2p::swarm::SwarmEvent::NewListenAddr { address, .. } => {
                println!("监听地址: {}", address);
            }
            libp2p::swarm::SwarmEvent::Behaviour(event) => {
                match event {
                    libp2p::ping::Event { peer, result, .. } => {
                        match result {
                            Ok(rtt) => println!("Ping 成功: 对等节点 {} RTT: {:?}", peer, rtt),
                            Err(e) => println!("Ping 失败: 对等节点 {} 错误: {:?}", peer, e),
                        }
                    }
                }
            }
            libp2p::swarm::SwarmEvent::ConnectionEstablished { peer_id, .. } => {
                println!("连接建立: 对等节点 {}", peer_id);
            }
            libp2p::swarm::SwarmEvent::ConnectionClosed { peer_id, cause, .. } => {
                println!("连接关闭: 对等节点 {} 原因: {:?}", peer_id, cause);
            }
            _ => {}
        }
    }

    Ok(())
}